#!/usr/bin/ruby

require 'rubygems'
require 'mongo'
require 'uuid'

module MongoLock
	class Mutex
		#
		# 
		#
		def initialize db, name, lifespan=60
			@db = db
			@acquired = false
			@name = name
			@delay = lifespan

			uuidgen = UUID.new
			@uuid = uuidgen.generate
		end

		#
		# 
		#
		def try_acquire
			raise NotImplementedError
			#FIXME		compare_and_swap( @name, )
		end

		#
		# Request to acquire the mutex & lock process until it is acquired.
		# When acquired, the mutex is usable until released or until lifespan
		# delay is over.
		#
		# FIXME: explain the timeout
		#
		def acquire_timeout timeout
			remaining_time = timeout
			raise ArgumentError, "timeout should be greater or equal to zero" if timeout < 0
			while compare_and_swap( false, true ) do
				raise TimeoutError if ( timeout > 0 ) and ( remaining_time <= 0 )
				# register process into mutex X waiters
				# make the process sleep

				remaining_time = remaining_time - 1
				sleep 1
			end
			return true
		end

		#
		# Request to acquire the mutex & lock process until it is acquired.
		# When acquired, the mutex is usable until released or until lifespan
		# delay is over.
		#
		def acquire
			acquire_timeout 0
		end


		#
		# Works only for an acquired mutex
		#
		# Get another lifespan cycle for current mutex.
		#
		def renew
			
		end

		#
		# Release the mutex
		# 
		def release
			mutex = false
			# wake all sleeping processes
		end

		private

		def compare_and_swap oldval, newval
			mutex = { 
				:name => @name,
				:owner => @uuid,
				:expiration => DateTime.now + @delay
			}
			# insert first
			# if other exist ?
				
			# request creation if nothing exists
			# create structure if none does
			
			# true on fail
			return true 
		end
	end

end

